﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Json;
using System.Linq;
using System.Net.Http;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using AutoMapper;
using MvcApplication2.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace MvcApplication2.Controllers
{
    [Authorize]
    public class TesterController : ControllerEx
    {
        private MvcApplication2Context db = new MvcApplication2Context();

        public TesterController()
        {
            ViewBag.Layout = "~/Views/Shared/_TesterLayout.cshtml";
        }

        public ActionResult Index()
        {
            return View();
        }
       
        /// <summary>
        /// Mostra una lista degli esercizi compatibili ( per lingua e device )
        /// </summary>
        /// <returns></returns>
        public ActionResult SearchExercises(string sortBy = "PublishedDate", bool ascending = true, int page = 1, int pageSize = 10)
        {
            // non devo includere gli esercizi con i quali sono in corso
            var user = ModelHelper.GetUser(db);

            IEnumerable<Exercise> exercises = new List<Exercise>();
            /*
             * non filtro più in base a device.
             * in quanto per ora il mobile non è supportato
             */
            foreach (var language in user.Languages)
            {
                var language1 = language;
                var temp =
                    db.Exercises.Where(u => u.Owner.Languages.Any(l => l.LanguageId == language1.LanguageId));

                exercises = exercises.Union(temp);
            }

            //var exercises = (from t in db.Exercises
            //          from u in db.UsersProfiles
            //          where u.UserProfileId == user.UserProfileId
            //          from d in u.Devices
            //          from lan in u.Languages
            //          from lanOwner in t.Owner.Languages
            //          where d.DeviceId == t.DeviceId
            //          where lan.LanguageId == lanOwner.LanguageId
            //          where t.Status == "published"
            //          select t).ToList();

            //var vm = ModelHelper.CopyTo<List<Exercise>,TesterSearcExercisesViewModel>(p1);
            var vm = new SearchExercisesViewModel();

            vm.CanScreenCapture = user.CanPcScreencast;
            vm.CanWebcamRecording= user.CanRegisterMobileDevice;

            foreach (var exercise in exercises)
            {
                var ex = ModelHelper.CopyTo<Exercise, ExerciseFindTesterViewModel>(exercise);

                var alredySended =
                    (db.UserMessages.Include(m => m.UsersAllowed).Where(
                        m =>
                        m.ExerciseId == exercise.ExerciseId &&
                        m.Type == UserMessageType.TesterExercise &&
                        m.UsersAllowed.Any(o => o.UserProfileId == user.UserProfileId))).Any();

                var message = "No proposte in corso";

                if (alredySended)
                    message = "Proposta già spedita !";

                ex.ProposalSendedMessage = message;

                vm.Exercises.Add(ex);
            }

            return View(vm);
        }

        //public ActionResult AskDifferentPrice(int id = 0)
        //{
        //    var user = ModelHelper.GetUser(db);

        //    var viewModel = UserMessageHelper.GetProposal(id, db, true);

        //    if (viewModel == null) return RedirectToAction("MyExercises");

        //    return View("SendProposal", viewModel);
        //}

        //[HttpPost]
        //public ActionResult AskDifferentPrice(UserMessageViewModel proposal, FormCollection formCollection)
        //{
        //    var success = UserMessageHelper.CreateChildProposal(db, proposal.UserMessageId, proposal.Reward, proposal.Message,
        //                                                                "tester");
        //    if (success)
        //    {
        //        return RedirectToAction("MyExercises");
        //    }

        //    // todo: inserire messaggi di errore
        //    return RedirectToAction("SendProposal", proposal.UserMessageId);
        //}

        public ActionResult SendProposal(int id = 0)
        {
            var user = ModelHelper.GetUser(db);

            var exmessage = UserMessageHelper.TesterExerciseGet(db, id, user.UserProfileId);

            var vm = ModelHelper.CopyTo<UserMessage, UserMessageViewModel>(exmessage);

            return View(vm);
        }

        /// <summary>
        /// Qui verrà creato il messaggio di proposta
        /// </summary>
        [HttpPost]
        public ActionResult SendProposal(UserMessageViewModel mess, FormCollection formCollection)
        {

            var success = UserMessageHelper.TesterExercisePost(db, mess.ExerciseId, mess.TesterId, mess.Reward, mess.Message, "tester");

            if (success)
                AddSuccessMessage("Proposta Spedita !");

            else
            {
                AddErrorMessage("Errore spedizione proposta !");
            }

            return RedirectToAction("SearchExercises");
        }


        [HttpPost]
        public string ExerciseVideo()
        {
            foreach (string f in Request.Files.AllKeys)
            {
                var file = Request.Files[f];
                string root = System.Web.HttpContext.Current.Server.MapPath("~/App_Data/uploads/");

                if (file != null) file.SaveAs(root + file.FileName);
            }

            return "success";
        }

        //[Authorize]
        [AllowAnonymous]
        public string GetTesterExercise(string username, string password)
        {
            if (Membership.ValidateUser(username, password))
            {
                var mem = Membership.GetUser(username);
                var g = (Guid)mem.ProviderUserKey;

                using (var db = new MvcApplication2Context())
                {
                    var user = db.UsersProfiles.FirstOrDefault(l => l.MembershipGuid == g);

                    if (user == null) return "failed";

                    //      var workMsg1 =
                    //db.UserMessages.Include(t => t.Exercise).Where(m => m.Type == (byte)ThreadMessageType.TesterExercise).Where(
                    //    m1 => m1.TesterId == user.UserId).ToList();


                    var workMsg = from w in db.UserMessages.Include(t => t.Exercise)
                                  where w.Type == UserMessageType.TesterExercise
                                  where w.TesterId == user.UserProfileId
                                  where w.ExerciseStatus == ExerciseStatusType.WaitingTest
                                  select new
                                             {
                                                 Reward = w.Reward,
                                                 Title = w.Exercise.Title,
                                                 Author = w.Owner.DisplayName,
                                                 ExerciseId = w.UserMessageId,
                                             };
                    var l1 = new Dictionary<string, object>() { { "o", workMsg } };
                    var result = JsonConvert.SerializeObject(l1, Formatting.Indented);
                    //   System.Json.JsonObject o = new JsonObject(workMsg);
                    return result;
                }
            }
            else
            {
                return "failed";
            }


        }

        /// <summary>

        /// 
        /// Mostra una lista degli esercizi (proposte o già arrivati ad accordo), che sono da fare.
        /// Questi "esercizi" sono dei UserMessage, oppure devo fare classi specifiche.
        /// Per adesso provo ad usare ThredMessage poi vedrò..
        /// </summary>
        /// <returns></returns>
        public ActionResult MyExercises(string filter)
        {
            var user = ModelHelper.GetUser(db);

            var vms = UserMessageHelper.GetExercises(db, user.UserProfileId, true);

            //ViewBag.Layout = "~/Views/Shared/_TesterLayout.cshtml";

            // Prendo i messaggi che hanno come tipo == work
            // dove sono owner 
            // o dove sono tra utenti abilitati
            //var workMsg =
            //    db.UserMessages.Include(t => t.Exercise).Where(m => m.Type == (byte)ThreadMessageType.TesterExercise).Where(
            //        m1 => m1.Owner.UserId == user.UserId || m1.UsersAllowed.Any(m2 => m2.UserId == user.UserId)).ToList();

            //var workMsg =
            //    db.UserMessages.Include(t => t.Exercise).Where(m => m.Type == ThreadMessageType.TesterExercise).Where(
            //        m1 => m1.TesterId == user.UserId).ToList();

            //var vms = ModelHelper.GetListViewModel<UserMessage, ExerciseTestViewModel>(workMsg);

            //foreach (var vm in vms)
            //{
            //    vm.IsTesterSide = true;
            //}
            return View(vms);
        }


        public ActionResult AcceptTestExercise(int id = 0)
        {
            var test = db.UserMessages.Find(id);

            test.ExerciseStatus = ExerciseStatusType.WaitingTest;

            db.SaveChanges();

            return RedirectToAction("MyExercises");
        }

        public ActionResult TrashProposal(int id = 0)
        {
            var user = ModelHelper.GetUser(db);

            var test = db.UserMessages.Find(id);

            if (test != null)
            {

                test.LastMessageFrom = "tester";

                test.ExerciseStatus = ExerciseStatusType.Rejected;

                if (test.UsersAllowed.Contains(user))
                    test.UsersAllowed.Remove(user);

                db.SaveChanges();

                /*
             * vedere come fare per cancellarlo.
             */
            }

            return RedirectToAction("MyExercises");
        }

        //public ActionResult VoteUser(int id = 0)
        //{
        //    //if(tmessage == 0)
        //    //{
        //    var ex = db.UserMessages.Include(o => o.UserMessages).FirstOrDefault(o => o.UserMessageId == id);

        //    if (ex == null) return RedirectToAction("MyExercises");

        //    var testerRating = ex.UserMessages.FirstOrDefault(l => l.Type == UserMessageType.RatingDev);

        //    if (testerRating == null) return RedirectToAction("MyExercises");

        //    // magari creo vm
        //    return View(testerRating);
        //}

        //[HttpPost]
        //public ActionResult VoteUser(UserMessage user, FormCollection formCollection)
        //{
        //    var ratingThread = db.UserMessages.Find(user.UserMessageId);

        //    var messagge = formCollection["Message"];
        //    var rating = formCollection["Rating"];

        //    ratingThread.Message = messagge;
        //    ratingThread.Rating = byte.Parse(rating);

        //    db.SaveChanges();

        //    return RedirectToAction("MyExercises");

        //}

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}
